package com.edu.zut.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.zut.domain.LoginInfo;
import com.edu.zut.domain.LoginUser;
import com.edu.zut.domain.RegisterVo;
import com.edu.zut.entity.User;
import com.edu.zut.entity.UserRole;
import com.edu.zut.mapper.RoleMapper;
import com.edu.zut.mapper.UserMapper;
import com.edu.zut.mapper.UserRoleMapper;
import com.edu.zut.result.HttpCode;
import com.edu.zut.result.ResponseResult;
import com.edu.zut.service.UserService;
import com.edu.zut.utils.JwtUtil;
import com.edu.zut.utils.QiniuUtil;
import org.apache.commons.io.FilenameUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 许文科
 * @since 2023-01-12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private UserMapper userMapper;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private UserRoleMapper userRoleMapper;

    /**
     * 实现登录逻辑
     *
     * @param user
     * @return
     */
    @Override
    public ResponseResult login(User user) {

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        //如果认证通过，给出提示
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("登录失败");
        }
        //如果认证通过，生成token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();//获取认证对象
        String username = loginUser.getUsername().toString();
        List<String> roleNames = loginUser.getRoleNames();

        if (roleNames.isEmpty()) {
            return new ResponseResult(HttpCode.ERROR, "角色已停用，请联系管理员.", null);
        }

        LoginInfo loginInfo = userMapper.getLoginUserInfo(user.getUserName());
        if (loginInfo.getStatus().equals("1")) {
            return new ResponseResult(HttpCode.UNAUTHORIZED, "帐户已停用,请联系管理员", null);
        }

        String token = JwtUtil.sign(username, roleNames);
        loginInfo.setToken(token);

        return new ResponseResult(HttpCode.SUCCESS, "成功", loginInfo);
    }

    /**
     * 实现注册逻辑
     *
     * @param registerVo
     * @return
     */
    @Override
    public ResponseResult register(RegisterVo registerVo) {
        //先查找
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", registerVo.getUsername());
        User findUser = userMapper.selectOne(wrapper);

        //存在，不可以注册
        if (findUser != null) {
            return new ResponseResult(HttpCode.CONFLICT, "注册失败，用户名重复", null);
        }

        //1.将用户信息插入到sys_user（密码要加密）中，并获取其user_id,userType=0 admin,=0 teacher,=1 student=2;
        User insertUser = new User();
        insertUser.setUserName(registerVo.getUsername());

        if (registerVo.getRole() == "ROLE_teacher") {
            insertUser.setUserType("1");
        } else {//Role_student
            insertUser.setUserType("2");
        }

        //密码加密
        String encodePassword = passwordEncoder.encode(registerVo.getPassword());
        insertUser.setPassword(encodePassword);

        //更新sys_user表
        int insertFlag = userMapper.insert(insertUser);

        if (insertFlag == 1) {
            //2.根据registerVo.getRole()，查询sys_role中的role_id，然后将user_id和role_id插入到sys_user_role中

            //根据角色名查找role_id
            Long roleId = roleMapper.getRoleIdByRoleName(registerVo.getRole());
            //查找user_id
            Long userId = userMapper.getUserIdByUserName(registerVo.getUsername());
            //将role_id和user_id插入到sys_user_role表中
            UserRole user_Role = new UserRole();
            user_Role.setUserId(userId);
            user_Role.setRoleId(roleId);
            int insertUserRoleFlag = userRoleMapper.insert(user_Role);

            if (insertUserRoleFlag == 0) {
                return new ResponseResult(HttpCode.NO_CONTENT, "注册失败", null);
            }
        }

        return new ResponseResult(HttpCode.SUCCESS, "注册成功，请登录", null);
    }

    @Override
    public ResponseResult getStudentsList() {

        QueryWrapper<User> wrapper = new QueryWrapper<User>().orderByAsc("user_id");
        //未被删除的，且类型为2的学生
        wrapper.eq("user_type", '2').or().eq("user_type", '1').and(r -> r.eq("del_flag", 0));
        List<User> userList = userMapper.selectList(wrapper);
        if (!userList.isEmpty())
            return new ResponseResult(HttpCode.SUCCESS, "获取成功", userList);
        else
            return new ResponseResult(HttpCode.NO_CONTENT, "获取失败", null);
    }

    @Override
    public ResponseResult addStudent(User user) {
        QueryWrapper<User> wrapper = new QueryWrapper<User>();
        wrapper.eq("user_name", user.getUserName());
        User user1 = userMapper.selectOne(wrapper);
        if (user1 != null) {
            return new ResponseResult(HttpCode.CONFLICT, "添加失败,用户名重复", null);
        }
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //更新sys_user表
        int flag = userMapper.insert(user);

        //更新sys_user_role表
        if (flag == 1) {
            User user2 = userMapper.selectOne(wrapper);
            UserRole userRole = new UserRole();
            userRole.setUserId(user2.getUserId());
            if (user2.getUserType().equals("2")) {
                userRole.setRoleId(3L);
            }
            if (user2.getUserType().equals("1")) {
                userRole.setRoleId(2L);
            }
            if (user2.getUserType().equals("0")) {
                userRole.setRoleId(1L);
            }
            int insert = userRoleMapper.insert(userRole);
            if (insert == 1) {
                return new ResponseResult(HttpCode.SUCCESS, "添加成功", null);
            }
        }

        return new ResponseResult(HttpCode.ERROR, "添加失败", null);
    }

    @Override
    public ResponseResult updateStatus(Long userId, String status) {
        //System.out.println("status:" + status);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        User user = userMapper.selectOne(wrapper.eq("user_id", userId));

        user.setStatus(status);
//        wrapper.eq("user_id", userId).setEntity(user);
        int flag = userMapper.updateById(user);
        if (flag == 1) {
            return new ResponseResult("200", "修改成功", null);
        }
        return new ResponseResult("400", "修改失败", null);
    }

    @Override
    public ResponseResult edit(User user) {

//        System.out.println(user);

        //先查出来
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        User u = userMapper.selectOne(wrapper.eq("user_id", user.getUserId()));

        u.setUserName(user.getUserName());

        if (!user.getPassword().equals(u.getPassword())) {
            u.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        u.setPhonenumber(user.getPhonenumber());
        u.setUserNumber(user.getUserNumber());
        u.setSex(user.getSex());
        u.setUserType(user.getUserType());

        int flag = userMapper.updateById(u);
        if (flag == 1) {
            return new ResponseResult(HttpCode.SUCCESS, "修改成功.", null);
        }
        return new ResponseResult("400", "修改失败.", null);
    }

    @Override
    public ResponseResult find(User user) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", user.getUserName())
                .or().eq("user_number", user.getUserNumber());
        List<User> userList = userMapper.selectList(wrapper);
        if (userList != null) {
            return new ResponseResult("200", "成功", userList);
        }
        return new ResponseResult("400", "失败", null);
    }

    @Override
    public ResponseResult deleteUser(Long userId) {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        User user = userMapper.selectOne(wrapper);
        user.setDelFlag(1);
        int i = userMapper.updateById(user);
//        int i = userMapper.deleteById(userId);
        if (i == 1) {
            return new ResponseResult("200", "删除成功", null);
        }
        return new ResponseResult("400", "删除失败", null);
    }

    @Override
    public ResponseResult deleteUsers(Long userId) {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        User user = userMapper.selectOne(wrapper);
        user.setDelFlag(1);
        int i = userMapper.updateById(user);

        if (i == 1) {
            return new ResponseResult(HttpCode.SUCCESS, "删除成功", null);
        }
        return new ResponseResult(HttpCode.BAD_REQUEST, "删除失败", null);
    }

    @Override
    public ResponseResult modifyPassword(Long userId, String password, String newPassword) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        User user = userMapper.selectOne(wrapper.eq("user_id", userId));

        if (!passwordEncoder.matches(password, user.getPassword())) {
            return new ResponseResult(HttpCode.ERROR, "原密码不匹配，输入错误", null);
        } else {
            newPassword = passwordEncoder.encode(newPassword);
            userMapper.modifyPassword(userId, newPassword);
            return new ResponseResult(HttpCode.SUCCESS, "修改成功", null);
        }
    }

    @Override
    public ResponseResult avatar(MultipartFile file) {
        String url;
        int flag;//更新成功标志
        if (file == null) {
            return new ResponseResult(HttpCode.ERROR, "文件为空", null);
        }
        try {
            byte[] bytes = file.getBytes();//将文件转化为 byte[] 格式
            String name = UUID.randomUUID().toString().replace("-", "");//更改后的文件名
            String ext = FilenameUtils.getExtension(file.getOriginalFilename());//获取文件后缀
            String ur = name + "." + ext;
            url = new QiniuUtil().uploadBybyte(bytes, ur);

            //获取当前登录用户的用户名
            String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

            //将url更新为该用户的头像
            flag = userMapper.updateAvator(username, url);

            if (flag == 1) {
                return new ResponseResult(HttpCode.SUCCESS, "修改成功", url);
            }
            return new ResponseResult(HttpCode.SUCCESS, "修改成功", url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResponseResult(HttpCode.ERROR, "更新失败", null);
    }

    @Override
    public ResponseResult getUserRate() {
        //获取管理员数量
        int admin = userMapper.getTotalNumByUserType("0");
        //获取教师数量
        int teacher = userMapper.getTotalNumByUserType("1");
        //获取学生数量
        int student = userMapper.getTotalNumByUserType("2");

        int[] array = {admin, teacher, student};

        return new ResponseResult(HttpCode.SUCCESS, "成功", array);
    }

    @Override
    public ResponseResult info(String userName, String userNumber, String phoneNumber, String sex) {
        //更新个人信息

        LocalDateTime updateTime = LocalDateTime.now();

        int flag = userMapper.updateInfoByUserName(userName, userNumber, phoneNumber, sex, updateTime);
        if (flag == 1) {
            LoginInfo loginUserInfo = userMapper.getLoginUserInfo(userName);
            return new ResponseResult(HttpCode.SUCCESS, "修改成功", loginUserInfo);
        }
        return new ResponseResult(HttpCode.ERROR, "修改失败", null);
    }

    @Override
    public ResponseResult findPassword(String userName, String userPhone, String newPassword) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        wrapper.eq("phonenumber", userPhone);
        User user = userMapper.selectOne(wrapper);
        if (user == null) {
            return new ResponseResult(HttpCode.ERROR, "用户名或手机号不匹配", null);
        }
        user.setPassword(passwordEncoder.encode(newPassword));//密码加密
        int flag = userMapper.updateById(user);
        if (flag == 1) {
            return new ResponseResult(HttpCode.SUCCESS, "重置成功，请登录", null);
        }
        return new ResponseResult(HttpCode.ERROR, "重置失败", null);
    }


}
